//
// Created by 张玭 on 24-6-17.
//

#include "../HeadFiles/workerManager.h"
#include "../HeadFiles/employee.h"
#include "../HeadFiles/manager.h"
#include "../HeadFiles/boss.h"
#include "../HeadFiles/utils.h"
#include "../HeadFiles/worker.h"

workerManager::workerManager() {
    cout << "workerManager的构造函数调用" << endl;
    this->m_EmpNum = 0;
    this->m_EmpArray = NULL;
}

workerManager::~workerManager() {
    cout << "workerManager的析构函数调用" << endl;
}

void workerManager::showMenu() {
    cout << "**********************" << endl;
    cout << "***** 0.退出程序 *****" << endl;
    cout << "***** 1.添加职工 *****" << endl;
    cout << "***** 2.显示职工 *****" << endl;
    cout << "***** 3.删除职工 *****" << endl;
    cout << "***** 4.修改职工 *****" << endl;
    cout << "***** 5.查找职工 *****" << endl;
    cout << "***** 6.排序职工 *****" << endl;
    cout << "***** 7.清空文档 *****" << endl;
    cout << "**********************" << endl;
}

void workerManager::showEmp() const {
    cout << "显示职工" << endl;
    if (this->m_EmpNum == 0) {
        cout << "当前记录为空" << endl;
    } else {
        cout << "当前记录人数为：" << this->m_EmpNum << endl;
        for (int i = 0; i < this->m_EmpNum; i++) {
            this->m_EmpArray[i]->showInfo();
        }
    }
}

void workerManager::exitSystem() {
    cout << "退出程序，欢迎下次使用" << endl;
    exit(0);
}

void workerManager::addEmp() {
    cout << "添加职工" << endl;
    /*修改以根据实际人数进行增加*/
    cout << "请输入添加职工的个数" << endl;
    int addNum = 0; //这个只是为了可以降低操作成本，一次性设置空间大小
    cin >> addNum;
    if (addNum > 0) {
        //计算新空间的大小
        int realSize = 0; //记录真正添加人数
        //开辟新空间
        Worker **newSpace = new Worker *[addNum];

        //输入新的数据
        for (int i = 0; i < addNum; i++) {
            int id;
            string name;
            int dSelect;
            cout << "请输入第" << i + 1 << "个新职工编号" << endl;
            cin >> id;
            //判断id是否重复，重复充新输入
            while (this->m_EmpIds.find(id) != this->m_EmpIds.end()) {
                cout << "id重复" << endl;
                cout << "请重新输入第" << i + 1 << "个新职工编号" << endl;
                cin >> id;
            }
            cout << "请输入第" << i + 1 << "个新职工姓名" << endl;
            cin >> name;
            cout << "请选择该职工的岗位：" << endl;
            cout << "1、普通职工" << endl;
            cout << "2、经理" << endl;
            cout << "3、老板" << endl;
            cin >> dSelect;
            Worker *worker = NULL;
            switch (dSelect) {
                case 1:
                    worker = new Employee(id, name, 1);
                    break;
                case 2:
                    worker = new Manager(id, name, 2);
                    break;
                case 3:
                    worker = new Boss(id, name, 3);
                    break;
                default:
                    cout << "岗位输入有误，默认为员工" << endl;
                    worker = new Employee(id, name, 1); //默认为普通职工
                    break;
            }
            worker->showInfo(); //展示信息
            cout << "是否正确并添加：Y/N" << endl;
            char confirm;
            cin >> confirm;
            if (confirm == 'Y' || confirm == 'y') {
                newSpace[realSize] = worker;
                realSize++;
                this->m_EmpIds.insert(id);
                cout << "添加成功" << endl;
            } else {
                delete worker;
            }
        }
        cout << "成功添加了" << realSize << "个员工" << endl;
        showWorkerInfo(newSpace, realSize);
        //最终的空间
        Worker **finalSpace = new Worker *[this->m_EmpNum + realSize];
        //将原来空间下数据存放到新空间下
        if (this->m_EmpArray != NULL) {
            for (int i = 0; i < this->m_EmpNum; i++) {
                finalSpace[i] = this->m_EmpArray[i];
            }
        }
        //将新空间下数据存放到最终空间下
        if (realSize > 0) {
            for (int i = 0; i < realSize; i++) {
                finalSpace[this->m_EmpNum + i] = newSpace[i];
            }
        }
        //释放原有空间
        delete[] this->m_EmpArray;
        //释放newSpace
        delete[] newSpace;
        //更改新空间指向
        this->m_EmpArray = finalSpace;
        //更改新的个数
        this->m_EmpNum = realSize + this->m_EmpNum;
        // for (int i = realSize; i < newSize; i++) {
        //     this->m_EmpArray[i] = NULL;
        // }//没必要这么麻烦，因为下一次增加员工的时候是通过m_EmpNum进行拷贝的，多余的空间中的不会被拷贝，所以不会有问题。而且会通过delete[] this->m_EmpArray;释放掉多余的空间
        //提示信息
        cout << "成功添加" << addNum << "名新职工" << endl;
        this->saveToFile(); //保存数据到文件中
    } else {
        cout << "输入数据有误" << endl;
    }
    //按任意键后清屏，返回上级目录
    system("pause");
    system("cls");
}

void workerManager::saveToFile() {
    ofstream ofs;
    ofs.open(FILENAME, ios::out);
    for (int i = 0; i < this->m_EmpNum; i++) {
        ofs << this->m_EmpArray[i]->m_Id << " "
                << this->m_EmpArray[i]->m_Name << " "
                << this->m_EmpArray[i]->m_DeptId << endl;
    }
    ofs.close();
}

void workerManager::readFromFile() {
    ifstream ifs;
    ifs.open(FILENAME, ios::in); // 打开文件
    //文件不存在
    if (!ifs.is_open()) {
        cout << "文件不存在，正在创建新文件" << endl;
        ofstream ofs(FILENAME); // 创建新文件
        ofs.close(); // 关闭新文件
        this->m_EmpNum = 0; // 如果文件不存在，设置员工数量为0
        this->m_EmpArray = NULL; // 并将员工数组设置为NULL
        return;
    }
    //文件为空
    char ch;
    ifs >> ch;
    if (ifs.eof()) {
        cout << "文件为空" << endl;
        this->m_EmpNum = 0; // 如果文件为空，设置员工数量为0
        this->m_EmpArray = NULL; // 并将员工数组设置为NULL
        ifs.close();
        return;
    }

    //文件不为空，有数据
    ifs.clear(); // 清除错误状态
    ifs.seekg(0); //重新开始读取
    // 获取文件中的员工数量
    int count = 0;
    int m_Id;
    string m_Name;
    int m_DeptId;
    while (ifs >> m_Id && ifs >> m_Name && ifs >> m_DeptId) {
        count++;
    }

    // 根据员工数量创建数组
    this->m_EmpNum = count;
    this->m_EmpArray = new Worker *[this->m_EmpNum];

    // 重新从头读文件，将数据存入数组
    ifs.clear(); // 清除错误状态，因为上面已经读取过一次了，必须先清楚错误状态再移动指针到开始
    ifs.seekg(0);
    int index = 0;
    while (ifs >> m_Id && ifs >> m_Name && ifs >> m_DeptId) {
        //判断id是否重复
        if (this->m_EmpIds.find(m_Id) == this->m_EmpIds.end()) {
            Worker *worker = NULL;
            this->m_EmpIds.insert(m_Id);
            switch (m_DeptId) {
                case 1:
                    worker = new Employee(m_Id, m_Name, m_DeptId);
                    break;
                case 2:
                    worker = new Manager(m_Id, m_Name, m_DeptId);
                    break;
                case 3:
                    worker = new Boss(m_Id, m_Name, m_DeptId);
                    break;
                default:
                    cout << "文件数据有误" << endl;
            }
            this->m_EmpArray[index] = worker;
            index++;
        } else {
            cout << "文件数据有误，id重复" << endl;
            cout << "id:" << m_Id << " name:" << m_Name << " deptId:" << m_DeptId << endl;
        }
    }
    ifs.close();
}

void workerManager::delEmp() {
    cout << "删除职工" << endl;
    if (this->m_EmpNum == 0) {
        cout << "当前记录为空" << endl;
    } else {
        cout << "请输入要删除的职工编号" << endl;
        int id;
        cin >> id;
        int index = this->isExist(id);
        if (index != -1) {
            for (int i = index; i < this->m_EmpNum - 1; i++) {
                this->m_EmpArray[i] = this->m_EmpArray[i + 1];
            }
            this->m_EmpIds.erase(id);
            this->m_EmpNum--;
            this->saveToFile();
            cout << "删除成功" << endl;
        } else {
            cout << "删除失败，未找到该职工" << endl;
        }
    }
}

int workerManager::isExist(int id) const {
    //并没有考虑到id重复的情况，因此需要在新增的功能中确保id不重复
    if (this->m_EmpIds.find(id) == this->m_EmpIds.end()) return -1;
    for (int j = 0; j < this->m_EmpNum; j++) {
        if (this->m_EmpArray[j]->m_Id == id) {
            return j;
        }
    }
    return -1;
}

vector<int> workerManager::isExist(const string &name) const {
    /*
    在C++中，当你返回一个局部对象（如std::vector<int>）时，
    C++会自动进行返回值优化（Return Value Optimization，RVO），
    或者叫做（Named）Return Value Optimization，NRVO）。
    这是一种编译器优化技术，用于避免额外的拷贝或移动操作。
    */
    vector<int> indices;
    for (int j = 0; j < this->m_EmpNum; j++) {
        if (this->m_EmpArray[j]->m_Name == name) {
            indices.push_back(j);
        }
    }
    return indices;
}

void workerManager::printEmpIds() const {
    cout << "所有的id有:" << endl;
    for (set<int>::iterator it = this->m_EmpIds.begin(); it != this->m_EmpIds.end(); it++) {
        cout << *it << " ";
    }
}

void workerManager::modEmp() {
    if (this->m_EmpNum == 0) {
        cout << "当前记录为空" << endl;
    } else {
        printEmpIds();
        cout << "请输入要修改的职工编号" << endl;
        int id;
        cin >> id;
        int index = isExist(id);
        if (index != -1) {
            cout << "找到了" << endl;
            int newId;
            while (true) {
                cout << "请输入新的职工编号" << endl;
                cin >> newId;
                if (newId != id && this->m_EmpIds.find(newId) != this->m_EmpIds.end()) {
                    cout << "新的id已经存在" << endl;
                } else {
                    break;
                }
            }
            cout << "请输入新的职工姓名" << endl;
            string newName;
            cin >> newName;
            cout << "请输入新的职工岗位" << endl;
            cout << "1、普通职工" << endl;
            cout << "2、经理" << endl;
            cout << "3、老板" << endl;
            int newDeptId;
            cin >> newDeptId;
            Worker *worker = NULL;
            switch (newDeptId) {
                case 1:
                    worker = new Employee(newId, newName, newDeptId);
                    break;
                case 2:
                    worker = new Manager(newId, newName, newDeptId);
                    break;
                case 3:
                    worker = new Boss(newId, newName, newDeptId);
                    break;
                default:
                    cout << "岗位输入有误，默认为员工" << endl;
                    worker = new Employee(newId, newName, 1); //默认为普通职工
                    break;
            }
            worker->showInfo(); //展示信息
            cout << "是否正确并添加：Y/N" << endl;
            char confirm;
            cin >> confirm;
            if (confirm == 'Y' || confirm == 'y') {
                delete this->m_EmpArray[index];
                this->m_EmpArray[index] = worker;
                cout << "修改成功" << endl;
                this->saveToFile();
                this->m_EmpIds.erase(id);
                this->m_EmpIds.insert(newId);
            } else {
                delete worker;
            }
        } else {
            cout << "查无此人" << endl;
        }
    }
    system("pause");
    system("cls");
}

void workerManager::findEmp() {
    cout << "查找职工" << endl;
    cout << "请输入查找方式" << endl;
    cout << "1、按职工编号查找" << endl;
    cout << "2、按职工姓名查找" << endl;
    int select;
    cin >> select;
    if (select == 1) {
        cout << "请输入查找的职工编号" << endl;
        int id;
        cin >> id;
        int index = isExist(id);
        if (index != -1) {
            this->m_EmpArray[index]->showInfo();
        } else {
            cout << "查无此人" << endl;
        }
    } else if (select == 2) {
        cout << "请输入查找的职工姓名" << endl;
        string name;
        cin >> name;
        vector<int> indices = isExist(name);
        if (!indices.empty()) {
            for (int i = 0; i < indices.size(); i++) {
                this->m_EmpArray[indices[i]]->showInfo();
            }
        } else {
            cout << "查无此人" << endl;
        }
    } else {
        cout << "输入有误" << endl;
    }
}

void workerManager::sortEmp() {
    if (this->m_EmpNum == 0) {
        cout << "当前记录为空" << endl;
        system("pause");
        system("cls");
    } else {
        cout << "请选择排序方式：" << endl;
        cout << "1、按职工号升序" << endl;
        cout << "2、按职工号降序" << endl;
        int select;
        cin >> select;
        for (int i = 0; i < this->m_EmpNum; i++) {
            int minOrMax = i;
            for (int j = i + 1; j < this->m_EmpNum; j++) {
                if (select == 1) {
                    if (this->m_EmpArray[minOrMax]->m_Id > this->m_EmpArray[j]->m_Id) {
                        minOrMax = j;
                    }
                } else {
                    if (this->m_EmpArray[minOrMax]->m_Id < this->m_EmpArray[j]->m_Id) {
                        minOrMax = j;
                    }
                }
            }
            if (i != minOrMax) {
                Worker *temp = this->m_EmpArray[i];
                this->m_EmpArray[i] = this->m_EmpArray[minOrMax];
                this->m_EmpArray[minOrMax] = temp;
            }
        }
        cout << "排序成功" << endl;
        this->saveToFile();
        this->showEmp();
    }
}

void workerManager::clearFile() {
    cout << "清空文件" << endl;
    cout << "确认清空？Y/N" << endl;
    char confirm;
    cin >> confirm;
    if (confirm == 'Y' or confirm == 'y') {
        ofstream ofs(FILENAME, ios::trunc);
        ofs.close();
        if (this->m_EmpArray != NULL) {
            for (int i = 0; i < this->m_EmpNum; ++i) {
                if (this->m_EmpArray[i] != NULL) {
                    delete this->m_EmpArray[i];
                    this->m_EmpArray[i] = NULL;
                }
            }
            this->m_EmpNum = 0;
            this->m_EmpIds.clear();
            delete[] this->m_EmpArray;
            this->m_EmpArray = NULL;
        }
        cout << "清空成功" << endl;
    }
}
